iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0
Software Development

從Servlet到Spring MVC系列 第 25

Day24 Spring MVC - Review Spring Framework (1)

  • 分享至 

  • xImage
  •  

前言

今日我們將快速瀏覽Spring Framework作為日後Spring MVC的基礎。

0、創建module

create day24 module
https://ithelp.ithome.com.tw/upload/images/20241009/201280845xj0QByv2O.png
create resource folder
https://ithelp.ithome.com.tw/upload/images/20241009/201280841valKowPSy.png
generate spring configuration file
https://ithelp.ithome.com.tw/upload/images/20241009/20128084gOs9tsM07L.png

二、Spring Framework

Spring兩大核心概念DI與AOP。DI幫你解偶物件間的相依,不用再到處new物件了;AOP替你解偶程式流程耦合的橫切面關注。

(1) DI

談到Spring常會聽到Inversion of Control(IoC)控制反轉,反轉了物件生成控制權,將控制權交給了Spring Container,但IoC有多種的意思,筆者更頃向用Dependency Injection(DI)依賴注入說明它。

(2) AOP

Aspect Oriented Programming (AOP)面向導向編程,關注cross-cutting concerns指的是非商業邏輯的關注點,像是logging、transactions、autit等。

三、DI Containers

DI Container是一個運行在JVM上的Java程式,它負責創建、配置、組裝物件與管理物件生命週期,所以他能容易整合AOP功能。它串建物建透過單純的POJO與設定檔資訊產生出符合系統使用的物件。
https://ithelp.ithome.com.tw/upload/images/20241009/20128084FAjgOjWSEX.png

四、Use Spring

(1) XML Schema-based configuration

pom.xml引入spring使用的相關jar

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version> 6.1.13</version>
    </dependency>
  </dependencies>

前面提及的spring container創建物件是由pojo與configuration meta組合起來的,所以會有一個乘載設定檔的文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 最簡單的注入範例   -->
    <bean id="emp01" class="com.swj.xml.Employee">
        <property name="empNo" value="1234"></property>
        <property name="name" value="joe"></property>
    </bean>

    <!-- 引入外部設定檔後可用${}來取用設定檔資訊 -->
    <context:property-placeholder location="classpath:dbConfig.properties"></context:property-placeholder>

    <!-- HikariCP connection pool setting -->
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <!-- jdbc setting -->
        <property name="driverClassName" value="${db.driverClassName}" />
        <property name="jdbcUrl" value="${db.url}" />
        <property name="username" value="${db.username}" />
        <property name="password" value="${db.password}" />

        <!-- HikariCP parameter setting -->
        <property name="maximumPoolSize" value="${db.hikari.maximumPoolSize}" />
        <property name="minimumIdle" value="${db.hikari.minimumIdle}" />
        <property name="idleTimeout" value="${db.hikari.idleTimeout}" />
        <property name="connectionTimeout" value="${db.hikari.connectionTimeout}" />
        <property name="maxLifetime" value="${db.hikari.maxLifetime}" />
    </bean>

    <bean id="empDao" class="com.swj.xml.EmpDao">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>
    <bean id="empService" class="com.swj.xml.EmpService">
        <constructor-arg ref="empDao"></constructor-arg>
    </bean>
    <bean id="empController" class="com.swj.xml.EmpController">
        <constructor-arg ref="empService"></constructor-arg>
    </bean>

</beans>
# dbConfig.properties
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mydb
db.username=root
db.password=1234

# connection pool setting
db.hikari.maximumPoolSize=10
db.hikari.minimumIdle=5
db.hikari.idleTimeout=30000
db.hikari.connectionTimeout=30000
db.hikari.maxLifetime=1800000

EmpController

public class EmpController {
    private EmpService empService;

    public void doEmpController() throws SQLException {
        System.out.println("invoke doEmpController");
        empService.doEmpService();
    }

    public EmpController(EmpService empService) {
        this.empService = empService;
    }

}

EmpService

public class EmpService {

    private EmpDao empDao;

    public void doEmpService() throws SQLException {
        System.out.println("invoke doEmpService");
        empDao.doEmpDao();
    }

    public EmpService(EmpDao empDao) {
        this.empDao = empDao;
    }
}
public class EmpDao {
    private DataSource ds;

    public void doEmpDao() throws SQLException {
        System.out.println("invoke doEmpDao");
        System.out.println("ds info:"+ds.getConnection());
    }

    public EmpDao(DataSource ds) {
        this.ds = ds;
    }
}

Employee

public class Employee {
  String name;
  String empNo;
  //略getter、setter and toString
}

TestXml.java展示創建DI container並調用bean執行doEmpController方法

public class TestXml {
    public static void main( String[] args ) throws SQLException {
        ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("beans.xml");
        Employee emp01 = (Employee) container.getBean("emp01");
        System.out.println(emp01);

        EmpController controller = container.getBean(EmpController.class);
        controller.doEmpController();
    }
}

Demo

https://ithelp.ithome.com.tw/upload/images/20241009/20128084AjunzHkwz3.png

Reference


上一篇
Day23 Servlet - Project
下一篇
Day25 Spring MVC - Review Spring Framework (2)
系列文
從Servlet到Spring MVC36
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言